#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const int MAXN = 200005; // n <= 1e5 保证安全
struct SegNode { int l, r, sum; } tr[MAXN * 4];

int n, m;
vector<int> g[MAXN];
int fa[MAXN], dep[MAXN], siz[MAXN], son[MAXN];
int top[MAXN], dfn[MAXN], seg[MAXN], cntd;

void dfs1(int x, int f) {
    fa[x] = f;
    dep[x] = dep[f] + 1;
    siz[x] = 1; son[x] = 0;
    int mx = 0;
    for (int y : g[x]) if (y != f) {
        dfs1(y, x);
        siz[x] += siz[y];
        if (siz[y] > mx) mx = siz[y], son[x] = y;
    }
}
void dfs2(int x, int t) {
    top[x] = t;
    dfn[x] = ++cntd;
    seg[cntd] = x;
    if (!son[x]) return;
    dfs2(son[x], t);
    for (int y : g[x]) if (y != fa[x] && y != son[x]) dfs2(y, y);
}

void build(int id, int l, int r) {
    tr[id].l = l; tr[id].r = r; tr[id].sum = 0;
    if (l == r) return;
    int mid = (l + r) >> 1;
    build(id << 1, l, mid);
    build(id << 1 | 1, mid + 1, r);
}
void pull(int id) { tr[id].sum = tr[id << 1].sum + tr[id << 1 | 1].sum; }

// set position p to 1 (mark). id is segment-tree node index
void modify(int id, int p) {
    if (tr[id].l == tr[id].r) {
        tr[id].sum = 1;
        return;
    }
    int mid = (tr[id].l + tr[id].r) >> 1;
    if (p <= mid) modify(id << 1, p);
    else modify(id << 1 | 1, p);
    pull(id);
}

// query sum on [L,R]
int query_sum(int id, int L, int R) {
    if (L > R) return 0;
    if (L <= tr[id].l && tr[id].r <= R) return tr[id].sum;
    int mid = (tr[id].l + tr[id].r) >> 1, res = 0;
    if (L <= mid) res += query_sum(id << 1, L, R);
    if (R > mid) res += query_sum(id << 1 | 1, L, R);
    return res;
}

// find rightmost position in [L,R] that has sum>0, return its index (dfn), or 0 if none
int query_last(int id, int L, int R) {
    if (L > R || tr[id].sum == 0) return 0;
    if (tr[id].l == tr[id].r) return tr[id].l;
    int mid = (tr[id].l + tr[id].r) >> 1;
    // prefer right child to get the most-deep (largest dfn) position
    if (R > mid) {
        int res = query_last(id << 1 | 1, L, R);
        if (res) return res;
    }
    if (L <= mid) return query_last(id << 1, L, R);
    return 0;
}

// return node id of nearest marked ancestor of x
int query_nearest_anc(int x) {
    while (top[x] != top[1]) {
        int L = dfn[top[x]], R = dfn[x];
        if (query_sum(1, L, R) > 0) {
            int pos = query_last(1, L, R);
            return seg[pos];
        }
        x = fa[top[x]];
    }
    // finally in chain of root(=1)
    int pos = query_last(1, dfn[1], dfn[x]);
    return seg[pos];
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    if (!(cin >> n >> m)) return 0;
    for (int i = 1; i <= n; ++i) g[i].clear();
    for (int i = 1; i < n; ++i) {
        int u, v; cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dep[0] = 0;
    dfs1(1, 0);
    cntd = 0;
    dfs2(1, 1);
    build(1, 1, n);
    // initially node 1 is marked
    modify(1, dfn[1]);

    while (m--) {
        char op; int x;
        cin >> op >> x;
        if (op == 'C') { // mark
            modify(1, dfn[x]);
        } else { // 'Q' query nearest marked ancestor
            cout << query_nearest_anc(x) << '\n';
        }
}
    return 0;
}
